package com.cencat.driver.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.cencat.common.entity.BaseEntity;
import jakarta.validation.constraints.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 配送任务实体类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("delivery_task")
public class DeliveryTask extends BaseEntity {

    /**
     * 任务ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 任务编号
     */
    @NotBlank(message = "任务编号不能为空")
    @Size(max = 32, message = "任务编号长度不能超过32个字符")
    @TableField("task_no")
    private String taskNo;

    /**
     * 订单ID
     */
    @NotNull(message = "订单ID不能为空")
    @TableField("order_id")
    private Long orderId;

    /**
     * 司机ID
     */
    @TableField("driver_id")
    private Long driverId;

    /**
     * 车辆ID
     */
    @TableField("vehicle_id")
    private Long vehicleId;

    /**
     * 任务类型：1-配送，2-取货，3-退货
     */
    @NotNull(message = "任务类型不能为空")
    @Min(value = 1, message = "任务类型值不能小于1")
    @Max(value = 3, message = "任务类型值不能大于3")
    @TableField("task_type")
    private Integer taskType;

    /**
     * 任务状态：0-待分配，1-已分配，2-已接受，3-配送中，4-已完成，5-已取消，6-异常
     */
    @Min(value = 0, message = "任务状态值不能小于0")
    @Max(value = 6, message = "任务状态值不能大于6")
    @TableField("task_status")
    private Integer taskStatus;

    /**
     * 优先级：1-低，2-中，3-高，4-紧急
     */
    @NotNull(message = "优先级不能为空")
    @Min(value = 1, message = "优先级值不能小于1")
    @Max(value = 4, message = "优先级值不能大于4")
    @TableField("priority")
    private Integer priority;

    /**
     * 取货地址
     */
    @NotBlank(message = "取货地址不能为空")
    @Size(max = 255, message = "取货地址长度不能超过255个字符")
    @TableField("pickup_address")
    private String pickupAddress;

    /**
     * 取货经度
     */
    @NotNull(message = "取货经度不能为空")
    @DecimalMin(value = "-180.0", message = "取货经度值不能小于-180")
    @DecimalMax(value = "180.0", message = "取货经度值不能大于180")
    @TableField("pickup_lng")
    private BigDecimal pickupLng;

    /**
     * 取货纬度
     */
    @NotNull(message = "取货纬度不能为空")
    @DecimalMin(value = "-90.0", message = "取货纬度值不能小于-90")
    @DecimalMax(value = "90.0", message = "取货纬度值不能大于90")
    @TableField("pickup_lat")
    private BigDecimal pickupLat;

    /**
     * 取货联系人
     */
    @NotBlank(message = "取货联系人不能为空")
    @Size(max = 50, message = "取货联系人长度不能超过50个字符")
    @TableField("pickup_contact")
    private String pickupContact;

    /**
     * 取货联系电话
     */
    @NotBlank(message = "取货联系电话不能为空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "取货联系电话格式不正确")
    @TableField("pickup_phone")
    private String pickupPhone;

    /**
     * 取货时间窗开始
     */
    @TableField("pickup_time_start")
    private LocalDateTime pickupTimeStart;

    /**
     * 取货时间窗结束
     */
    @TableField("pickup_time_end")
    private LocalDateTime pickupTimeEnd;

    /**
     * 配送地址
     */
    @NotBlank(message = "配送地址不能为空")
    @Size(max = 255, message = "配送地址长度不能超过255个字符")
    @TableField("delivery_address")
    private String deliveryAddress;

    /**
     * 配送经度
     */
    @NotNull(message = "配送经度不能为空")
    @DecimalMin(value = "-180.0", message = "配送经度值不能小于-180")
    @DecimalMax(value = "180.0", message = "配送经度值不能大于180")
    @TableField("delivery_lng")
    private BigDecimal deliveryLng;

    /**
     * 配送纬度
     */
    @NotNull(message = "配送纬度不能为空")
    @DecimalMin(value = "-90.0", message = "配送纬度值不能小于-90")
    @DecimalMax(value = "90.0", message = "配送纬度值不能大于90")
    @TableField("delivery_lat")
    private BigDecimal deliveryLat;

    /**
     * 配送联系人
     */
    @NotBlank(message = "配送联系人不能为空")
    @Size(max = 50, message = "配送联系人长度不能超过50个字符")
    @TableField("delivery_contact")
    private String deliveryContact;

    /**
     * 配送联系电话
     */
    @NotBlank(message = "配送联系电话不能为空")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "配送联系电话格式不正确")
    @TableField("delivery_phone")
    private String deliveryPhone;

    /**
     * 配送时间窗开始
     */
    @TableField("delivery_time_start")
    private LocalDateTime deliveryTimeStart;

    /**
     * 配送时间窗结束
     */
    @TableField("delivery_time_end")
    private LocalDateTime deliveryTimeEnd;

    /**
     * 预估距离（公里）
     */
    @DecimalMin(value = "0.0", message = "预估距离不能小于0")
    @TableField("estimated_distance")
    private BigDecimal estimatedDistance;

    /**
     * 预估时长（分钟）
     */
    @Min(value = 0, message = "预估时长不能小于0")
    @TableField("estimated_duration")
    private Integer estimatedDuration;

    /**
     * 实际距离（公里）
     */
    @DecimalMin(value = "0.0", message = "实际距离不能小于0")
    @TableField("actual_distance")
    private BigDecimal actualDistance;

    /**
     * 实际时长（分钟）
     */
    @Min(value = 0, message = "实际时长不能小于0")
    @TableField("actual_duration")
    private Integer actualDuration;

    /**
     * 货物信息（JSON）
     */
    @TableField("goods_info")
    private String goodsInfo;

    /**
     * 货物重量（公斤）
     */
    @DecimalMin(value = "0.0", message = "货物重量不能小于0")
    @TableField("goods_weight")
    private BigDecimal goodsWeight;

    /**
     * 货物体积（立方米）
     */
    @DecimalMin(value = "0.0", message = "货物体积不能小于0")
    @TableField("goods_volume")
    private BigDecimal goodsVolume;

    /**
     * 配送费用
     */
    @DecimalMin(value = "0.0", message = "配送费用不能小于0")
    @TableField("delivery_fee")
    private BigDecimal deliveryFee;

    /**
     * 特殊要求
     */
    @Size(max = 500, message = "特殊要求长度不能超过500个字符")
    @TableField("special_requirements")
    private String specialRequirements;

    /**
     * 分配时间
     */
    @TableField("assign_time")
    private LocalDateTime assignTime;

    /**
     * 接受时间
     */
    @TableField("accept_time")
    private LocalDateTime acceptTime;

    /**
     * 取货时间
     */
    @TableField("pickup_time")
    private LocalDateTime pickupTime;

    /**
     * 开始配送时间
     */
    @TableField("start_delivery_time")
    private LocalDateTime startDeliveryTime;

    /**
     * 完成时间
     */
    @TableField("complete_time")
    private LocalDateTime completeTime;

    /**
     * 取消时间
     */
    @TableField("cancel_time")
    private LocalDateTime cancelTime;

    /**
     * 取消原因
     */
    @Size(max = 255, message = "取消原因长度不能超过255个字符")
    @TableField("cancel_reason")
    private String cancelReason;

    /**
     * 异常原因
     */
    @Size(max = 255, message = "异常原因长度不能超过255个字符")
    @TableField("exception_reason")
    private String exceptionReason;

    /**
     * 备注
     */
    @Size(max = 500, message = "备注长度不能超过500个字符")
    @TableField("remark")
    private String remark;

    /**
     * 租户ID
     */
    @NotNull(message = "租户ID不能为空")
    @TableField("tenant_id")
    private Long tenantId;

    // 任务类型枚举常量
    public static final int TYPE_DELIVERY = 1;  // 配送
    public static final int TYPE_PICKUP = 2;    // 取货
    public static final int TYPE_RETURN = 3;    // 退货

    // 任务状态枚举常量
    public static final int STATUS_PENDING = 0;     // 待分配
    public static final int STATUS_ASSIGNED = 1;    // 已分配
    public static final int STATUS_ACCEPTED = 2;    // 已接受
    public static final int STATUS_DELIVERING = 3;  // 配送中
    public static final int STATUS_COMPLETED = 4;   // 已完成
    public static final int STATUS_CANCELLED = 5;   // 已取消
    public static final int STATUS_EXCEPTION = 6;   // 异常

    // 优先级枚举常量
    public static final int PRIORITY_LOW = 1;       // 低
    public static final int PRIORITY_MEDIUM = 2;    // 中
    public static final int PRIORITY_HIGH = 3;      // 高
    public static final int PRIORITY_URGENT = 4;    // 紧急

    /**
     * 获取任务类型描述
     */
    public String getTaskTypeDesc() {
        switch (this.taskType) {
            case TYPE_DELIVERY: return "配送";
            case TYPE_PICKUP: return "取货";
            case TYPE_RETURN: return "退货";
            default: return "未知";
        }
    }

    /**
     * 获取任务状态描述
     */
    public String getTaskStatusDesc() {
        switch (this.taskStatus) {
            case STATUS_PENDING: return "待分配";
            case STATUS_ASSIGNED: return "已分配";
            case STATUS_ACCEPTED: return "已接受";
            case STATUS_DELIVERING: return "配送中";
            case STATUS_COMPLETED: return "已完成";
            case STATUS_CANCELLED: return "已取消";
            case STATUS_EXCEPTION: return "异常";
            default: return "未知";
        }
    }

    /**
     * 获取优先级描述
     */
    public String getPriorityDesc() {
        switch (this.priority) {
            case PRIORITY_LOW: return "低";
            case PRIORITY_MEDIUM: return "中";
            case PRIORITY_HIGH: return "高";
            case PRIORITY_URGENT: return "紧急";
            default: return "未知";
        }
    }

    /**
     * 判断任务是否可以被接受
     */
    public boolean canBeAccepted() {
        return STATUS_ASSIGNED == this.taskStatus;
    }

    /**
     * 判断任务是否正在进行中
     */
    public boolean isInProgress() {
        return STATUS_ACCEPTED == this.taskStatus || 
               STATUS_DELIVERING == this.taskStatus;
    }

    /**
     * 判断任务是否已完成
     */
    public boolean isCompleted() {
        return STATUS_COMPLETED == this.taskStatus;
    }

    /**
     * 判断任务是否已取消
     */
    public boolean isCancelled() {
        return STATUS_CANCELLED == this.taskStatus;
    }

    /**
     * 判断任务是否异常
     */
    public boolean isException() {
        return STATUS_EXCEPTION == this.taskStatus;
    }

    /**
     * 判断是否超时（基于配送时间窗）
     */
    public boolean isOverdue() {
        if (deliveryTimeEnd == null) {
            return false;
        }
        return LocalDateTime.now().isAfter(deliveryTimeEnd) && !isCompleted();
    }

    /**
     * 计算任务总时长（分钟）
     */
    public Integer getTotalDuration() {
        if (assignTime == null || completeTime == null) {
            return null;
        }
        return (int) java.time.Duration.between(assignTime, completeTime).toMinutes();
    }
}